package com.eu.mybatis.partition;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.eu.mybatis.config.InterceptorConfig;
import com.eu.mybatis.config.PartitionConfig;
import com.eu.mybatis.config.TableConfig;
import com.eu.mybatis.exception.EuMybatisException;
import com.eu.mybatis.helper.PartitionConfigHelper;

public class PartitionHandler {

	private static Logger logger = LoggerFactory.getLogger(PartitionHandler.class);

//	private static final String limit_offset = "LIMIT ? OFFSET ?";

	private static final ConcurrentMap<String, Boolean> cache = new ConcurrentHashMap<String, Boolean>();

	public PartitionHandler() {
		PartitionConfigHelper.initPartitionConfig();
	}

	public void handle(InterceptorConfig interceptorConfig) throws EuMybatisException {
		if (isPartitionConfig(interceptorConfig)) {
			String convertedSql = convertSql(interceptorConfig);
			interceptorConfig.setValue("boundSql.sql", convertedSql);
		}
	}

	private String convertSql(InterceptorConfig interceptorConfig) throws EuMybatisException {
		// 参数
		Object params = interceptorConfig.getParameterObject();
		// dao层方法id
		String mappedId = interceptorConfig.getMappedId();
		// sql语句
		String sql = interceptorConfig.getSql();

		 //方法一：转换分表sql
		String convertedSql = sql;
		for (String tableName : PartitionConfig.getConvertTables()) {
			if (convertedSql.contains(tableName)) {
				for (TableConfig tableConfig : PartitionConfig.getTableConfigs(tableName)) {
					if (convertedSql.contains(tableConfig.getTableName())) {
						convertedSql = convertedSql.replaceAll(tableConfig.getTableNameConvert(),
								tableConfig.getBefore() + PartitionConfig.getStrategy(tableName).getTargetTableName(tableName, params, mappedId) + tableConfig.getAfter());
					}
				}
			}
		}

//		 方法二：转换分表sql
//		String convertedSql = SqlConverterFactory.getInstance().convert(sql, params, mappedId);
//		if (sql.toUpperCase().indexOf(limit_offset) == -1) {
//			int limit = convertedSql.toUpperCase().indexOf(limit_offset);
//			if (limit > -1) {
//				convertedSql = convertedSql.substring(0, limit) + "LIMIT ?, ?";
//			}
//		}

		if (logger.isDebugEnabled()) {
			logger.debug("Converted Sql [" + mappedId + "]: " + convertedSql);
		}

		return convertedSql;
	}

	private boolean isPartitionConfig(InterceptorConfig interceptorConfig) {
		
		if(!PartitionConfig.strategyDefined()) {
			return false;
		}
		
		String mappedId = interceptorConfig.getMappedId();

		if (cache.get(mappedId) == null) {
			
			boolean isPartition = false;

			String sqlUpper = interceptorConfig.getSql().toUpperCase();
			
			for (String tableName : PartitionConfig.getTableNames()) {
				if (sqlUpper.contains(tableName)) {
					isPartition = true;
					break;
				}
			}

			cache.put(mappedId, isPartition);
		}
		
		return cache.get(mappedId);
	}

}